////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// THIS IS AUTO-GENERATED CODE.  PLEASE DO NOT EDIT (File bug reports against tools).
///
/// Auto-generated by: ParameterParser V1.1.4
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  parameterfilesymboltableentry.h
/// @brief Auto-generated Chromatix parameter file
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PARAMETERSYMBOLTABLEENTRY_H
#define PARAMETERSYMBOLTABLEENTRY_H

#include "parametertypes.h"
#include "parameterutils.h"

/*******************************************************************************
* Forward declarations
*******************************************************************************/
class ParameterFileSymbolTable;

class ParameterFileSymbolTableEntry
{
public:
    // ID 0 is reserved for Parent ID to indicate the entry is a Module
    static const UINT32 MODULE_PARENT_ID = 0;
    static const UINT32 START_ID         = 1;
    static const INT32  TYPE_LEN         = 32;
    static const INT32  TYPE_START_LEN   = TYPE_LEN / 4;
    static const INT32  TYPE_END_LEN     = TYPE_LEN - TYPE_START_LEN - 1;
    static const CHAR   TYPE_SEPARATOR   = '-';
    static const INT32  PREFIX_COUNT     = 2;

    // Symbol table entry size as defined in the Chromatix Data Access Design document
    static const INT32  SYMBOL_ENTRY_SIZE = 4 +       // ID
                                            TYPE_LEN +// Type
                                            2 +       // Version: Major
                                            2 +       // Version: Minor
                                            4 +       // Version: Patch
                                            2 +       // Mode
                                            2 +       // Selector
                                            4 +       // Selector Data
                                            4 +       // Parent ID
                                            4 +       // Data Offset
                                            4;        // Data Size

    static const INT32  MODE_ENTRY_SIZE =   4 +       // ID
                                            2 +       // Mode
                                            2 +       // SubMode
                                            4 +       // Group
                                            4;        // Parent ID

    ParameterFileSymbolTableEntry()
    {
        Table      = NULL;
        m_position = 0;
        m_data     = NULL;
    }

    ~ParameterFileSymbolTableEntry()
    {
        m_data = NULL;
    }

    VOID Init(
        ParameterFileSymbolTable* table)
    {
        Table      = table;
        m_position = 0;
        m_data     = NULL;
    }

    BOOL Load(
        BYTE*   buffer,
        UINT64  length,
        UINT64* pos,
        UINT32  dataOffset)
    {
        BOOL      result        = true;
        UINT32    offset        = 0;
        m_data = NULL;
        result = result & ParameterUtils::ReadUInt32(&ID,           buffer, length, pos);
        ParameterUtils::ReadString(Type, buffer, length, pos, TYPE_LEN + 1, TYPE_LEN);
        result = result & ParameterUtils::ReadUInt16(&Major,        buffer, length, pos);
        result = result & ParameterUtils::ReadUInt16(&Minor,        buffer, length, pos);
        result = result & ParameterUtils::ReadUInt32(&Patch,        buffer, length, pos);
        result = result & ParameterUtils::ReadUInt16(&Mode,         buffer, length, pos);
        result = result & ParameterUtils::ReadUInt16(&SubMode,      buffer, length, pos);
        result = result & ParameterUtils::ReadUInt32(&Group,        buffer, length, pos);
        result = result & ParameterUtils::ReadUInt32(&ModeId,       buffer, length, pos);
        result = result & ParameterUtils::ReadUInt32(&offset,       buffer, length, pos);
        result = result & ParameterUtils::ReadUInt32(&m_dataSize,   buffer, length, pos);
        m_data = buffer + dataOffset + offset;

        return result;
    }

    static CHAR* GetType(
        CHAR*       outputType,
        const CHAR* moduleName)
    {
        const CHAR* prefixes[] = { "chromatix_", "chromatix" };
        const CHAR* type       = moduleName;

        for (UINT64 i = 0; i < PREFIX_COUNT; i++)
        {
            SIZE_T len = PARAMETER_STRLEN(prefixes[i]);
            if ((PARAMETER_STRNICMP(moduleName, prefixes[i], len) == 0) &&
                 (len < PARAMETER_STRLEN(moduleName)))
            {
                type = &moduleName[len];
                break;
            }
        }

        UINT64 typeLen = (UINT64)PARAMETER_STRLEN(type);
        if (typeLen > TYPE_LEN)
        {
            for (UINT64 i = 0; i < TYPE_START_LEN; i++)
            {
                outputType[i] = type[i];
            }
            outputType[TYPE_START_LEN] = TYPE_SEPARATOR;
            UINT64 typePos = PARAMETER_STRLEN(type) - TYPE_END_LEN;
            UINT64 index   = TYPE_START_LEN + 1;
            while (typePos < typeLen)
            {
                outputType[index++] = type[typePos++];
            }

            outputType[TYPE_LEN] = '\0';
        }
        else
        {
            PARAMETER_STRCPY(outputType, TYPE_LEN + 1, type);
        }

        return outputType;
    }

    ParameterFileSymbolTable* Table;

    UINT32 ID;
    CHAR   Type[TYPE_LEN + 1];
    UINT16 Major;
    UINT16 Minor;
    UINT32 Patch;
    UINT16 Mode;
    UINT16 SubMode;
    UINT32 Group;
    UINT32 ModeId;

    BOOL IsModule()
    {
        const UINT32 NON_MODULE_PARENT_ID = 0xFFFFFFFF;
        return ModeId != NON_MODULE_PARENT_ID;
    }

    BOOL ReadInt8(
        INT8* value)
    {
        return ParameterUtils::ReadInt8(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadUInt8(
        UINT8* value)
    {
        return ParameterUtils::ReadUInt8(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadInt16(
        INT16* value)
    {
        return ParameterUtils::ReadInt16(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadUInt16(
        UINT16* value)
    {
        return ParameterUtils::ReadUInt16(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadInt32(
        INT32* value)
    {
        return ParameterUtils::ReadInt32(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadUInt32(
        UINT32* value)
    {
        return ParameterUtils::ReadUInt32(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadInt64(
        INT64* value)
    {
        return ParameterUtils::ReadInt64(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadUInt64(
        UINT64* value)
    {
        return ParameterUtils::ReadUInt64(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadBoolean(
        BOOL* value)
    {
        return ParameterUtils::ReadBoolean(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadFloat(
        FLOAT* value)
    {
        return ParameterUtils::ReadFloat(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadDouble(
        DOUBLE* value)
    {
        return ParameterUtils::ReadDouble(value, m_data, m_dataSize, &m_position);
    }

    BOOL ReadString(
        CHAR** value,
        UINT64 maxChars)
    {
        *value = ParameterUtils::ReadString(m_data, m_dataSize, &m_position, maxChars);
        return *value != NULL;
    }

    BOOL ReadCharArray(CHAR* value, SIZE_T max)
    {
        CHAR* source = (CHAR*)&m_data[m_position];
        for (UINT64 i = 0; i < max; i++)
        {
            value[i] = source[i];
        }
        m_position += max;
        return TRUE;
    }

    UINT32 ReadEnum(BOOL* result)
    {
        UINT32 value = 0;
        *result = *result && ParameterUtils::ReadUInt32(&value, m_data, m_dataSize, &m_position);
        return value;
    }

private:
    UINT32  m_dataSize;
    BYTE*   m_data;
    UINT64  m_position;
};

#endif

